package com.zsl.swing.redis.desktop.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.zsl.swing.redis.desktop.model.DbCountConfigEntity;
import com.zsl.swing.redis.desktop.model.FontSizeConfigEntity;
import com.zsl.swing.redis.desktop.model.NodeEntity;
import com.zsl.swing.redis.desktop.model.OtherGeneralConfigEntity;
import com.zsl.swing.redis.desktop.struct.FixedArrayList;
import com.zsl.swing.redis.desktop.window.ZslRedisDesktopMainWindow;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 
 * @author 张帅令
 * &#064;description  用于预加载连接配置或者最后保存更改后的配置
 *
 */
public class ConfigUtils {
	
	private static final String CONFIG_PATH = System.getProperty("user.home") + File.separator+ "RedisDesktop";
	
	private static final String SERVER_CONFIG_FILE_NAME = "server.json";

	private static final String FONT_SIZE_CONFIG_FILE_NAME = "font.json";

	private static final String DB_COUNT_CONFIG_FILE_NAME = "db_count.json";

	private static final String HISTORY_COMMAND_FILE_NAME = "history_command.json";

	private static final String OTHER_GENERAL_CONFIG_FILE_NAME = "other_general_config.json";
	
	private static final Charset DEFAULT_ENCODE = StandardCharsets.UTF_8;


	public static DbCountConfigEntity readDbCountConfig(){
		String dbCountConfigJson = readFile2String(DB_COUNT_CONFIG_FILE_NAME);
		if(!StringUtils.isEmpty(dbCountConfigJson)){
			return JSON.parseObject(dbCountConfigJson, DbCountConfigEntity.class);
		}else{
			DbCountConfigEntity configEntity = DbCountConfigEntity.defaultConfig();
			writeDbCountConfig(configEntity);
			return configEntity;
		}
	}

	public static boolean writeDbCountConfig(DbCountConfigEntity configEntity){
		return writeString2File(JSON.toJSONString(configEntity), DB_COUNT_CONFIG_FILE_NAME);
	}

	public static FontSizeConfigEntity readFontSizeConfig(){
		String fontConfigJson = readFile2String(FONT_SIZE_CONFIG_FILE_NAME);
		if(!StringUtils.isEmpty(fontConfigJson)){
			return JSON.parseObject(fontConfigJson,FontSizeConfigEntity.class);
		}else{
			FontSizeConfigEntity defaultConfig = FontSizeConfigEntity.defaultConfig();
			writeFontSizeConfig(defaultConfig);
			return defaultConfig;
		}

	}

	public static boolean writeFontSizeConfig(FontSizeConfigEntity fontSizeConfig){
		return writeString2File(JSON.toJSONString(fontSizeConfig),FONT_SIZE_CONFIG_FILE_NAME);
	}
	
	public static List<NodeEntity> readConnections(){
		String connectionsString = readFile2String(SERVER_CONFIG_FILE_NAME);
		
		if(StringUtils.isEmpty(connectionsString)) {
			return Collections.emptyList();
		}else {
			try {
				List<NodeEntity> nodeList = JSONArray.parseArray(connectionsString, NodeEntity.class);
				nodeList.forEach(one -> {
					if(StringUtils.isEmpty(one.getUsername())){
						one.setUsername(RedisUtils.DEFAULT_USERNAME);
					}
				});
				return nodeList;
			} catch (Exception e) {
				ZslRedisDesktopMainWindow.getZslLogPanel().logError(e);
				return Collections.emptyList();
			}
		}
	}

	@SuppressWarnings("all")
	private static void initConfigDirectory(){
		File file = new File(CONFIG_PATH);
		if(!file.exists()) {
			file.mkdirs();
		}
	}

	@SuppressWarnings("all")
	private static File getServerConfigFile(String fileName) {
		initConfigDirectory();

		File target = new File(CONFIG_PATH + File.separator + fileName);
		if(!target.exists()) {
			try {
				target.createNewFile();
			} catch (IOException e) {
				ZslRedisDesktopMainWindow.getZslLogPanel().logError(e);
			}
		}

		return target;
	}
	
	
	public static boolean writeConnections(List<NodeEntity> connectionEntities) {
		String targetString;
		if(CollectionUtils.isEmpty(connectionEntities)) {
			targetString = "";
		}else {
			targetString = JSONArray.toJSONString(connectionEntities);
		}

		return writeString2File(targetString,SERVER_CONFIG_FILE_NAME);
		
	}

	private static boolean writeString2File(String target, String fileName){
		FileOutputStream fos = null;
		try{
			fos = new FileOutputStream(getServerConfigFile(fileName));

			fos.write(target.getBytes(DEFAULT_ENCODE));
			fos.flush();
			return true;
		}catch (Exception e) {
			ZslRedisDesktopMainWindow.getZslLogPanel().logError(e);
			return false;
		}finally {
			if(fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					ZslRedisDesktopMainWindow.getZslLogPanel().logError(e);
				}
			}
		}

	}
	
	private static String readFile2String(String fileName) {
		File file = getServerConfigFile(fileName);
		try(
				BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(file.toPath()),DEFAULT_ENCODE))
				){
			StringBuilder sb = new StringBuilder();
			
			String line;
			while ((line = reader.readLine()) != null) {
				sb.append(line);
			}
			
			return sb.toString();
		}catch (Exception e) {
			ZslRedisDesktopMainWindow.getZslLogPanel().logError(e);
			return null;
		}
	}

	public static boolean saveConnection(NodeEntity entity) {
		List<NodeEntity> nodeEntities = readConnections();
		if(StringUtils.isEmpty(entity.getUniqueId())){
			entity.setUniqueId(UniqueIdUtils.getUniqueId());
			nodeEntities.add(entity);
		}else{
			nodeEntities = nodeEntities.stream().filter(e -> !e.getUniqueId().equals(entity.getUniqueId())).collect(Collectors.toList());
			nodeEntities.add(entity);
		}

		return writeConnections(nodeEntities);
	}

    public static boolean deleteConnection(NodeEntity entity) {
		List<NodeEntity> nodeEntities = readConnections();
		nodeEntities = nodeEntities.stream().filter(e -> !e.getUniqueId().equals(entity.getUniqueId())).collect(Collectors.toList());

		return writeConnections(nodeEntities);

	}

    public static FixedArrayList<String> readHistoryCommandList() {
		FixedArrayList<String> historyCommandList = new FixedArrayList<>(50);
		try{
			String historyJson = readFile2String(HISTORY_COMMAND_FILE_NAME);
			if(!StringUtils.isEmpty(historyJson)){
				List<String> jsonList = JSONArray.parseArray(historyJson, String.class);
				historyCommandList.addAll(jsonList);
			}

		}catch (Exception e){
			ZslRedisDesktopMainWindow.getZslLogPanel().log("加载历史命令失败---->");
		}

		return historyCommandList;
    }

	public static void writeHistoryCommandList(FixedArrayList<String> historyCommandList) {
		String historyJson = JSONArray.toJSONString(historyCommandList);
		writeString2File(historyJson,HISTORY_COMMAND_FILE_NAME);
	}

    public static OtherGeneralConfigEntity readOtherGeneralConfig() {
		String jsonResult = readFile2String(OTHER_GENERAL_CONFIG_FILE_NAME);
		if(!StringUtils.isEmpty(jsonResult)){
			return JSON.parseObject(jsonResult,OtherGeneralConfigEntity.class);
		}else{
			OtherGeneralConfigEntity defaultConfig = OtherGeneralConfigEntity.defaultConfig();
			writeString2File(JSON.toJSONString(defaultConfig),OTHER_GENERAL_CONFIG_FILE_NAME);
			return defaultConfig;
		}
    }

	public static boolean writeOtherGeneralConfig(OtherGeneralConfigEntity entity) {
		return writeString2File(JSON.toJSONString(entity), OTHER_GENERAL_CONFIG_FILE_NAME);
	}
}
